// 工具函数模块

// 球体配置
const BALL_CONFIG = {
    colors: [
        '#ff6b6b', // 1级 - 红色
        '#ffa726', // 2级 - 橙色
        '#ffeb3b', // 3级 - 黄色
        '#66bb6a', // 4级 - 绿色
        '#26c6da', // 5级 - 青色
        '#42a5f5', // 6级 - 蓝色
        '#ab47bc', // 7级 - 紫色
        '#ec407a', // 8级 - 粉色
        '#ffd700'  // 9级 - 金色
    ],
    // 9级球为容器宽度的1/3，其他等级依次缩小
    sizes: [20, 25, 30, 35, 40, 45, 50, 55, 63], // 对应1-9级的半径 (9级=380/3/2≈63)
    scores: [10, 20, 40, 80, 160, 320, 640, 1280, 2560] // 合成分数
};

// 游戏配置
const GAME_CONFIG = {
    canvas: {
        width: 400,
        height: 600
    },
    container: {
        width: 380,
        height: 500,
        x: 200,
        y: 550
    },
    physics: {
        gravity: 0.8,
        friction: 0.001,
        restitution: 0.3
    },
    gameplay: {
        maxBalls: 50,
        gameOverLine: 100,
        dropZone: {
            x: 50,
            y: 50,
            width: 300,
            height: 50
        }
    },
    CONTAINER_PADDING: 20,
    DROP_COOLDOWN: 500,
    
    // 动态更新容器配置
    updateContainer(canvasWidth, canvasHeight) {
        this.canvas.width = canvasWidth;
        this.canvas.height = canvasHeight;
        
        this.container.width = canvasWidth - 20;
        this.container.height = canvasHeight - 100;
        this.container.x = canvasWidth / 2;
        this.container.y = canvasHeight - 50;
        
        this.gameplay.dropZone.width = this.container.width - 100;
        this.gameplay.dropZone.x = (canvasWidth - this.gameplay.dropZone.width) / 2;
        
        // 动态更新球体大小 - 9级球为容器宽度的1/6
        const maxRadius = this.container.width / 6;
        const baseRadius = maxRadius / 9;
        BALL_CONFIG.sizes = [];
        for (let i = 1; i <= 9; i++) {
            BALL_CONFIG.sizes.push(Math.max(10, baseRadius * i));
        }
    }
};

// 工具函数类
class Utils {
    // 生成随机数
    static random(min, max) {
        return Math.random() * (max - min) + min;
    }

    // 生成随机整数
    static randomInt(min, max) {
        return Math.floor(Math.random() * (max - min + 1)) + min;
    }

    // 计算两点距离
    static distance(x1, y1, x2, y2) {
        return Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
    }

    // 角度转弧度
    static toRadians(degrees) {
        return degrees * (Math.PI / 180);
    }

    // 弧度转角度
    static toDegrees(radians) {
        return radians * (180 / Math.PI);
    }

    // 限制数值范围
    static clamp(value, min, max) {
        return Math.min(Math.max(value, min), max);
    }

    // 线性插值
    static lerp(start, end, factor) {
        return start + (end - start) * factor;
    }

    // 获取球体颜色
    static getBallColor(level) {
        return BALL_CONFIG.colors[level - 1] || BALL_CONFIG.colors[0];
    }

    // 获取球体大小
    static getBallSize(level) {
        return BALL_CONFIG.sizes[level - 1] || BALL_CONFIG.sizes[0];
    }

    // 获取合成分数
    static getMergeScore(level) {
        return BALL_CONFIG.scores[level - 1] || BALL_CONFIG.scores[0];
    }

    // 生成随机球体等级（1-3级较多，高级球较少）
    static generateRandomBallLevel() {
        const rand = Math.random();
        if (rand < 0.4) return 1;      // 40% 概率
        if (rand < 0.7) return 2;      // 30% 概率
        if (rand < 0.9) return 3;      // 20% 概率
        if (rand < 0.97) return 4;     // 7% 概率
        return 5;                      // 3% 概率
    }

    // 检查两个球是否可以合成
    static canMerge(ball1, ball2) {
        return ball1.level === ball2.level && ball1.level < 9;
    }

    // 创建增强粒子效果 - 爆炸特效与色差
    static createParticles(x, y, color, count = 8) {
        const particles = [];
        
        // 主爆炸粒子 - 径向扩散
        for (let i = 0; i < count * 2; i++) {
            const angle = (Math.PI * 2 * i) / (count * 2) + Utils.random(-0.3, 0.3);
            const velocity = Utils.random(3, 8);
            const particleType = Math.random();
            
            if (particleType < 0.4) {
                // 主要爆炸粒子
                particles.push({
                    x: x,
                    y: y,
                    vx: Math.cos(angle) * velocity,
                    vy: Math.sin(angle) * velocity,
                    color: color,
                    life: 1.0,
                    decay: Utils.random(0.015, 0.03),
                    size: Utils.random(3, 6),
                    type: 'explosion',
                    glowIntensity: Utils.random(0.5, 1.0),
                    chromaticOffset: Utils.random(1, 3)
                });
            } else if (particleType < 0.7) {
                // 发光星尘粒子
                particles.push({
                    x: x + Utils.random(-5, 5),
                    y: y + Utils.random(-5, 5),
                    vx: Math.cos(angle) * velocity * 0.6,
                    vy: Math.sin(angle) * velocity * 0.6,
                    color: '#ffffff',
                    life: 1.2,
                    decay: Utils.random(0.01, 0.025),
                    size: Utils.random(1, 3),
                    type: 'stardust',
                    sparkle: true,
                    sparklePhase: Utils.random(0, Math.PI * 2)
                });
            } else {
                // 魔法闪烁轨迹粒子
                particles.push({
                    x: x,
                    y: y,
                    vx: Math.cos(angle) * velocity * 1.5,
                    vy: Math.sin(angle) * velocity * 1.5,
                    color: Utils.getSparkleColor(),
                    life: 0.8,
                    decay: Utils.random(0.02, 0.04),
                    size: Utils.random(2, 4),
                    type: 'magic',
                    trail: [],
                    trailLength: 8
                });
            }
        }
        
        // 额外的冲击波粒子
        for (let i = 0; i < 3; i++) {
            particles.push({
                x: x,
                y: y,
                vx: 0,
                vy: 0,
                color: color,
                life: 0.6,
                decay: 0.05,
                size: 0,
                maxSize: 30 + i * 15,
                type: 'shockwave',
                alpha: 0.3 - i * 0.1
            });
        }
        
        return particles;
    }
    
    // 获取闪烁颜色
    static getSparkleColor() {
        const colors = ['#ff6b9d', '#4ecdc4', '#45b7d1', '#96ceb4', '#feca57', '#ff9ff3', '#54a0ff'];
        return colors[Math.floor(Math.random() * colors.length)];
    }

    // 更新增强粒子系统
    static updateParticles(particles) {
        const currentTime = Date.now();
        
        for (let i = particles.length - 1; i >= 0; i--) {
            const particle = particles[i];
            
            // 基础物理更新
            particle.x += particle.vx;
            particle.y += particle.vy;
            
            // 根据粒子类型应用不同的物理效果
            switch (particle.type) {
                case 'explosion':
                    particle.vy += 0.15; // 重力
                    particle.vx *= 0.98; // 空气阻力
                    particle.vy *= 0.98;
                    break;
                    
                case 'stardust':
                    particle.vy += 0.05; // 轻微重力
                    particle.vx *= 0.99; // 轻微阻力
                    particle.vy *= 0.99;
                    // 闪烁效果
                    if (particle.sparkle) {
                        particle.sparklePhase += 0.3;
                    }
                    break;
                    
                case 'magic':
                    // 魔法粒子轨迹记录
                    if (particle.trail) {
                        particle.trail.push({ x: particle.x, y: particle.y, life: particle.life });
                        if (particle.trail.length > particle.trailLength) {
                            particle.trail.shift();
                        }
                    }
                    particle.vy += 0.08; // 轻微重力
                    particle.vx *= 0.995;
                    particle.vy *= 0.995;
                    break;
                    
                case 'shockwave':
                    // 冲击波扩散
                    if (particle.size < particle.maxSize) {
                        particle.size += (particle.maxSize - particle.size) * 0.15;
                    }
                    break;
            }
            
            // 生命周期更新
            particle.life -= particle.decay;
            
            // 移除死亡粒子
            if (particle.life <= 0) {
                particles.splice(i, 1);
            }
        }
    }

    // 格式化分数显示
    static formatScore(score) {
        if (score >= 1000000) {
            return (score / 1000000).toFixed(1) + 'M';
        } else if (score >= 1000) {
            return (score / 1000).toFixed(1) + 'K';
        }
        return score.toString();
    }

    // 震动反馈（如果支持）
    static vibrate(duration = 100) {
        if (navigator.vibrate) {
            navigator.vibrate(duration);
        }
    }

    // 本地存储操作
    static saveToStorage(key, value) {
        try {
            localStorage.setItem(key, JSON.stringify(value));
        } catch (e) {
            console.warn('无法保存到本地存储:', e);
        }
    }

    static loadFromStorage(key, defaultValue = null) {
        try {
            const item = localStorage.getItem(key);
            return item ? JSON.parse(item) : defaultValue;
        } catch (e) {
            console.warn('无法从本地存储读取:', e);
            return defaultValue;
        }
    }

    // 防抖函数
    static debounce(func, wait) {
        let timeout;
        return function executedFunction(...args) {
            const later = () => {
                clearTimeout(timeout);
                func(...args);
            };
            clearTimeout(timeout);
            timeout = setTimeout(later, wait);
        };
    }

    // 节流函数
    static throttle(func, limit) {
        let inThrottle;
        return function() {
            const args = arguments;
            const context = this;
            if (!inThrottle) {
                func.apply(context, args);
                inThrottle = true;
                setTimeout(() => inThrottle = false, limit);
            }
        };
    }

    // 检查是否为移动设备
    static isMobile() {
        return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
    }

    // 检查是否支持触摸
    static isTouchDevice() {
        return 'ontouchstart' in window || navigator.maxTouchPoints > 0;
    }

    // 获取鼠标/触摸位置
    static getEventPosition(event, canvas) {
        const rect = canvas.getBoundingClientRect();
        // 使用显示尺寸进行坐标转换，而不是实际像素尺寸
        const displayWidth = parseFloat(canvas.style.width) || rect.width;
        const displayHeight = parseFloat(canvas.style.height) || rect.height;
        const scaleX = displayWidth / rect.width;
        const scaleY = displayHeight / rect.height;
        
        let clientX, clientY;
        
        if (event.touches && event.touches.length > 0) {
            clientX = event.touches[0].clientX;
            clientY = event.touches[0].clientY;
        } else {
            clientX = event.clientX;
            clientY = event.clientY;
        }
        
        return {
            x: (clientX - rect.left) * scaleX,
            y: (clientY - rect.top) * scaleY
        };
    }

    // 播放音效（如果音效系统可用）
    static playSound(soundName, volume = 1.0) {
        if (window.AudioManager) {
            window.AudioManager.playSound(soundName, volume);
        }
    }

    // 显示浮动文字效果
    static showFloatingText(canvasX, canvasY, text, color = '#fff', duration = 1000) {
        // 获取画布元素和位置信息
        const canvas = document.getElementById('gameCanvas');
        if (!canvas) return;
        
        const rect = canvas.getBoundingClientRect();
        const displayWidth = parseFloat(canvas.style.width) || rect.width;
        const displayHeight = parseFloat(canvas.style.height) || rect.height;
        
        // 将画布坐标转换为屏幕坐标
        const screenX = rect.left + (canvasX / displayWidth) * rect.width;
        const screenY = rect.top + (canvasY / displayHeight) * rect.height;
        
        const element = document.createElement('div');
        element.textContent = text;
        element.style.cssText = `
            position: fixed;
            left: ${screenX}px;
            top: ${screenY}px;
            color: ${color};
            font-weight: bold;
            font-size: 18px;
            pointer-events: none;
            z-index: 1000;
            text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
            animation: floatUp ${duration}ms ease-out forwards;
        `;
        
        // 添加CSS动画
        if (!document.getElementById('floatingTextStyle')) {
            const style = document.createElement('style');
            style.id = 'floatingTextStyle';
            style.textContent = `
                @keyframes floatUp {
                    0% { opacity: 1; transform: translateY(0px) scale(1); }
                    100% { opacity: 0; transform: translateY(-50px) scale(1.2); }
                }
            `;
            document.head.appendChild(style);
        }
        
        document.body.appendChild(element);
        
        setTimeout(() => {
            if (element.parentNode) {
                element.parentNode.removeChild(element);
            }
        }, duration);
    }
}

// 导出配置和工具类
if (typeof module !== 'undefined' && module.exports) {
    module.exports = { Utils, BALL_CONFIG, GAME_CONFIG };
}